/* eslint-disable no-restricted-globals */
/*
 * @Date: 2023-07-10 20:01:24
 * @LastEditors: 景冰川 961166897@qq.com
 * @LastEditTime: 2023-08-23 18:46:53
 * @FilePath: \veteran-cadre-app\src\util\utils.ts
 */
/**
 * @description 函数节流: 每隔一段时间，只执行一次函数
 * @param { Function } fn 需要延迟执行的函数
 * @param { Number } interval 延迟执行的时间，默认值500ms
 */
export function throttle(fn: Function, interval = 500) {
  // 记录定时器id
  let timer = null
  // 是否是第一次调用
  let isFirstTime = true

  return function () {
    // eslint-disable-next-line prefer-rest-params
    const args = arguments
    // eslint-disable-next-line @typescript-eslint/no-invalid-this, @typescript-eslint/no-this-alias
    const _me = this

    // 第一次直接执行,改变标志,无需延迟
    if (isFirstTime) {
      fn.apply(_me, args)
      return (isFirstTime = false)
    }

    // 不是第一次
    // 存在定时器,前面的延迟操作没有完成,直接返回,拒绝调用请求
    if (timer)
      return false

    // 延迟执行
    timer = setTimeout(() => {
      clearTimeout(timer)
      timer = null
      fn.apply(_me, args)
    }, interval)
  }
}

export function jsonToUrlParam(json) {
  return `?${Object.keys(json).map(key => `${key}=${json[key]}`).join('&')}`
}
export function backgroundBase64(path) {
  return `data:image/jpg;base64,${uni.getFileSystemManager().readFileSync(path, 'base64')}`
}
export function timeFormat(timestamp = null, fmt = 'yyyy-MM-dd hh:mm:ss') {
  timestamp = parseInt(timestamp)
  // 如果为null,则格式化当前时间
  if (!timestamp)
    timestamp = Number(new Date())
  // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
  if (timestamp.toString().length === 10)
    timestamp *= 1000
  const date = new Date(timestamp)
  let ret
  const opt = {
    'y+': date.getFullYear().toString(), // 年
    'M+': (date.getMonth() + 1).toString(), // 月
    'd+': date.getDate().toString(), // 日
    'h+': date.getHours().toString(), // 时
    'm+': date.getMinutes().toString(), // 分
    's+': date.getSeconds().toString(), // 秒
  }
  for (const k in opt) {
    ret = new RegExp(`(${k})`).exec(fmt)
    if (ret)
      fmt = fmt.replace(ret[1], ret[1].length === 1 ? opt[k] : opt[k].padStart(ret[1].length, '0'))
  }
  return fmt
}

export function isEmpty(value: any) {
  switch (typeof value) {
    case 'undefined':
      return true
    case 'string':
      if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length === 0)
        return true

      break
    case 'boolean':
      if (!value)
        return true
      break
    case 'number':

      if (value === 0 || isNaN(value))
        return true
      break
    case 'object':
      if (value === null || value.length === 0)
        return true
      // eslint-disable-next-line no-unreachable-loop
      for (const _i in value)
        return false

      return true
  }
  return false
}

// 数据
// 判断arr是否为一个数组，返回一个bool值
const isArray = (arr: any) => Object.prototype.toString.call(arr) === '[object Array]'
// 深度克隆
export function deepClone(obj: any) {
  if ([null, undefined, NaN, false].includes(obj))
    return obj
  if (typeof obj !== 'object' && typeof obj !== 'function')
    return obj
  const o = isArray(obj) ? [] : {}
  for (const i in obj) {
    if (Object.hasOwnProperty.call(obj, i))
      o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
  }
  return o
}
export function formatSeconds(value: number) {
  let secondTime: number | string = value
  let minuteTime: number | string = 0
  let hourTime: number | string = 0
  if (secondTime > 60) {
    minuteTime = (secondTime / 60).toFixed(1).slice(0, -2)
    secondTime = (secondTime % 60).toFixed(1).slice(0, -2)
    if (Number(minuteTime) > 60) {
      hourTime = (Number(minuteTime) / 60).toFixed(1).slice(0, -2)
      minuteTime = (Number(minuteTime) % 60).toFixed(1).slice(0, -2)
    }
  }
  if (Number(secondTime) === 0)
    secondTime = '00'
  else if (Number(secondTime) < 10)
    secondTime = `0${secondTime}`

  if (Number(minuteTime) === 0)
    minuteTime = '00'
  else if (Number(minuteTime) < 10)
    minuteTime = `0${minuteTime}`

  if (Number(hourTime) === 0)
    hourTime = '00'
  else if (Number(hourTime) < 10)
    hourTime = `0${hourTime}`

  const result = `${minuteTime}:${secondTime}`
  return result
}
export function encodeWAV(samples, numChannels, sampleRate) {
  const buffer = new ArrayBuffer(44 + samples.byteLength)
  const view = new DataView(buffer)
  /* RIFF identifier */
  writeString(view, 0, 'RIFF')
  /* RIFF chunk length */
  view.setUint32(4, 36 + samples.byteLength, true)
  /* RIFF type */
  writeString(view, 8, 'WAVE')
  /* format chunk identifier */
  writeString(view, 12, 'fmt ')
  /* format chunk length */
  view.setUint32(16, 16, true)
  /* sample format (raw) */
  view.setUint16(20, 1, true)
  /* channel count */
  view.setUint16(22, numChannels, true)
  /* sample rate */
  view.setUint32(24, sampleRate, true)
  /* byte rate (sample rate * block align) */
  view.setUint32(28, sampleRate * 4, true)
  /* block align (channel count * bytes per sample) */
  view.setUint16(32, numChannels * 2, true)
  /* bits per sample */
  view.setUint16(34, 16, true)
  /* data chunk identifier */
  writeString(view, 36, 'data')
  /* data chunk length */
  view.setUint32(40, samples.byteLength, true)

  copyBytes(view, 44, samples)

  return view
}
function copyBytes(output, offset, input) {
  const dataView = new DataView(input)
  for (let i = 0; i < input.byteLength; i++, offset++)
    output.setInt8(offset, dataView.getInt8(i))
}
function writeString(view, offset, string) {
  for (let i = 0; i < string.length; i++)
    view.setUint8(offset + i, string.charCodeAt(i))
}
